import requests
import os,snoop,re
import json

api_key = "bd07114ef49046e085d85a1ef9b7261a"
addr_str = '佛山市禅城区华宝南路13号'


class AddrLookup:
    """ 从高德api获取信息
    # url   https://restapi.amap.com/v3/geocode/geo?parameters
    params:
    key api_key of app
    address addr str，最好是结构化的地址信息，当然如果真的已经结构化了还用你干嘛
    city 城市设置，选填
    batch   批量查询，最多同时查询10个 True/False
    """
    def __init__(self,location_str:str,api_key:str)->None:
        """

        :param location_str:查找的str
        :param api_key:
        """
        self.location_str = location_str
        self.api_key = api_key
        self.lookup_initial_dict = self.addr2location()
        # self.lookup_secondary_dict = self.location2addr()
        # self.final_dict = self.final_dict_gen()
    def addr2location(self)->dict:
        """

        :return:根据init提供的 location_str 用地址编码api获得初步parse信息
        """

        res = requests.get(
            "https://restapi.amap.com/v3/geocode/geo",
            params={
                "key": self.api_key,
                "address": self.location_str,
                "batch": False,
            }
        )
        res_data = json.loads(res.text)
        if res_data['status']=='1':
            rsts = res_data['geocodes']
            if len(rsts)>1:
                snoop.pp(rsts)
                raise Exception("注意，返回多重地址结果")
            elif len(rsts)>0:
                return rsts[0]
            else:
                raise Exception(f'地址查询地理位置无结果:{self.location_str}')
        else:
            raise Exception(f'地址查询地理位置出现错误:{self.location_str}')
    def location2addr(self)->dict:
        """

        :return:根据 addr2location 获得的dict里面的location，用逆地理编码查找一个地址
        """
        location_str = self.lookup_initial_dict['location']
        res = requests.get(
            "https://restapi.amap.com/v3/geocode/regeo",
            params={
                "key": api_key,
                "location": location_str,
                "radius":300,
                "batch": False,
            }
        )
        res_data = json.loads(res.text)
        if res_data['status']=='1':
            return res_data
        else:
            raise Exception(f'逆地理查找{location_str}的时候出现错误')
    def primary_search_dict_gen(self)->dict:
        """
        工具func，只做地理编码，不进行逆地理编码
        :return: 地理编码返回的结果里，提取省市区三级信息，以及查找的地址信息
        """

        rst_dict = {}

        rst_dict['province']=self.lookup_initial_dict['province']
        rst_dict['city']=self.lookup_initial_dict['city']
        rst_dict['district']=self.lookup_initial_dict['district']
        rst_dict['lookup_str']=self.location_str
        return rst_dict

    def final_dict_gen(self)->dict:
        """
        调用地理编码和逆地理编码，返回包括town名称，编码在内的多种信息
        :return:dict包括了查找字符串，两次转换生成的标准地址，省市区县文本还有编码
        """
        rst_dict = {}

        self.lookup_secondary_dict = self.location2addr()
        loc2add_addr_comp = self.lookup_secondary_dict['regeocode']
        def same_or_nothing(field_name):
            if self.lookup_initial_dict[field_name]==loc2add_addr_comp['addressComponent'][field_name]:
                return loc2add_addr_comp['addressComponent'][field_name]
            else:
                snoop.pp(f"""初始查询所得结果与逆地理查询所得结果在{field_name}项结果不一致:
                init{self.lookup_initial_dict[field_name]},rev:{loc2add_addr_comp['addressComponent'][field_name]},
                查询地址:{self.location_str}""")
                return None
        rst_dict['lookup_str']=self.location_str
        rst_dict['primary_formatted_str']=self.lookup_initial_dict['formatted_address']
        rst_dict['secondary_formatted_str']=loc2add_addr_comp['formatted_address']
        rst_dict['province'] = same_or_nothing('province')
        rst_dict['city'] = same_or_nothing('city')
        rst_dict['district'] = same_or_nothing('district')
        rst_dict['township'] = loc2add_addr_comp['addressComponent']['township']
        rst_dict['towncode'] = loc2add_addr_comp['addressComponent']['towncode']
        return rst_dict

addr_lookup = AddrLookup(addr_str,api_key)
rst_dict = addr_lookup.final_dict_gen()